package com.example.demo.mybatisplus;

import com.example.demo.util.TemplateEngineUtil;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class CodeGeneratorService {

    @Autowired
    private  TemplateEngineUtil templateEngine;
    
    // 模板路径
    private static final String CONTROLLER_TEMPLATE = "controller.mustache";
    private static final String SERVICE_TEMPLATE = "service.mustache";
    private static final String SERVICE_IMPL_TEMPLATE = "serviceImpl.mustache";
    private static final String MAPPER_TEMPLATE = "mapper.mustache";
    private static final String MAPPER_XML_TEMPLATE = "mapper.xml.mustache";
    private static final String ENTITY_TEMPLATE = "entity.mustache";
    private static final String REQ_DTO_TEMPLATE = "reqDto.mustache";
    private static final String RESP_VO_TEMPLATE = "respVo.mustache";
    private static final String ASSEMBLER_TEMPLATE = "assembler.mustache";

    public CodeGeneratorService(TemplateEngineUtil templateEngine) {
        this.templateEngine = templateEngine;
    }

    public Map<String, String> generateCode(CodeGenConfig config) throws IOException {
        Map<String, Object> model = buildModel(config);
        Map<String, String> result = new HashMap<>();

        // 读取并处理各个模板
        result.put("controller.java", processTemplate(CONTROLLER_TEMPLATE, model));
        result.put("service.java", processTemplate(SERVICE_TEMPLATE, model));
        result.put("serviceImpl.java", processTemplate(SERVICE_IMPL_TEMPLATE, model));
        result.put("mapper.java", processTemplate(MAPPER_TEMPLATE, model));
        result.put("mapper.xml", processTemplate(MAPPER_XML_TEMPLATE, model));
        result.put("entity.java", processTemplate(ENTITY_TEMPLATE, model));
        result.put("reqDto.java", processTemplate(REQ_DTO_TEMPLATE, model));
        result.put("respVo.java", processTemplate(RESP_VO_TEMPLATE, model));
        result.put("assembler.java", processTemplate(ASSEMBLER_TEMPLATE, model));

        return result;
    }

    private Map<String, Object> buildModel(CodeGenConfig config) {
        Map<String, Object> model = new HashMap<>();
        
        // 基本信息
        model.put("className", config.getClassName());
        model.put("tableName", config.getTableName());
        model.put("pathName", config.getPathName());
        model.put("packagePath", config.getPackagePath());
        
        // 字段信息
        List<Map<String, Object>> fieldModels = config.getFields().stream()
            .map(field -> {
                Map<String, Object> fieldModel = new HashMap<>();
                fieldModel.put("columnName", field.getColumnName());
                fieldModel.put("propertyName", field.getPropertyName());
                fieldModel.put("propertyNameFirstUpper", capitalizeFirstLetter(field.getPropertyName()));
                fieldModel.put("javaType", field.getJavaType());
                fieldModel.put("comment", field.getComment());
                fieldModel.put("isString", "String".equals(field.getJavaType()));
                fieldModel.put("last", false); // 后续可以设置最后一个字段为true
                return fieldModel;
            })
            .collect(Collectors.toList());
        
        model.put("fields", fieldModels);
        return model;
    }

    private String processTemplate(String templateName, Map<String, Object> model) throws IOException {
        String templateContent = templateEngine.readTemplateFromClasspath(templateName);
        return templateEngine.processTemplate(templateContent, model);
    }

    private String capitalizeFirstLetter(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    public void saveGeneratedFiles(Map<String, String> generatedFiles, String baseOutputPath) throws IOException {
        File rootDir = new File(baseOutputPath);
        if (!rootDir.exists()) {
            rootDir.mkdirs();
        }

        for (Map.Entry<String, String> entry : generatedFiles.entrySet()) {
            String fileName = entry.getKey();  // 如：controller.java
            String content = entry.getValue();

            String relativePath;
            switch (fileName) {
                case "controller.java":
                    relativePath = "controller/";
                    break;
                case "service.java":
                    relativePath = "service/";
                    break;
                case "serviceImpl.java":
                    relativePath = "service/impl/";
                    break;
                case "mapper.java":
                    relativePath = "mapper/";
                    break;
                case "entity.java":
                    relativePath = "entity/";
                    break;
                case "reqDto.java":
                    relativePath = "dto/";
                    break;
                case "respVo.java":
                    relativePath = "vo/";
                    break;
                case "assembler.java":
                    relativePath = "util/";
                    break;
                case "mapper.xml":
                    relativePath = "resources/mapper/";
                    break;
                default:
                    relativePath = "";
            }

            // 构建完整路径并写入文件
            File dir = new File(rootDir, relativePath);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            File file = new File(dir, fileName.replace(".java", "") + ".java");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
                writer.write(content);
            }
        }
    }
}